//////////////////////////////////////////////
// System.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkGraphics
{
	class AsyncWorker ;
	class BlendStateManager ;
	class BufferManager ;
	class CameraManager ;
	class CompositorManager ;
	class ContentLoader ;
	class DepthStencilStateManager ;
	class LogManager ;
	class MeshDataLinkTracker ;
	class MeshManager ;
	class NodeManager ;
	class ProgramManager ;
	class RasterStateManager ;
	class RenderContext ;
	class RenderContextManager ;
	class Renderer ;
	class RenderQueueManager ;
	class ResourceManager ;
	class SamplerManager ;
	class ShaderManager ;
	class TextureManager ;
	class ViewportManager ;
}

namespace nkWinUi
{
	class System ;
}

/// Includes ---------------------------------

// nkGraphics
#include "Dll/DllDefines.h"

#include "Configurations/Configuration.h"

// nkMemory
#include <NilkinsMemory/Pointers/UniquePtr.h>

// Common
#include <nilkinsCommon/Patterns/MaybeSingletonClass.h>

// Standards
#include <functional>

/// Class ------------------------------------

namespace nkGraphics
{
	class DLL_GRAPHICS_EXPORT System final : public nkCommon::MaybeSingletonClass<System>
	{		
		public :
		
			// Constructor, destructor
			System () noexcept ;
			~System () ;

			// Getters
			nkWinUi::System* getUiSystem () const ;
			Renderer* getRenderer () const ;
			ContentLoader* getContentLoader () const ;
			MeshDataLinkTracker* getMeshDataLinkTracker () const ;
			AsyncWorker* getAsyncWorker () const ;
			BlendStateManager* getBlendStateManager () const ;
			BufferManager* getBufferManager () const ;
			CameraManager* getCameraManager () const ;
			CompositorManager* getCompositorManager () const ;
			DepthStencilStateManager* getDepthStencilStateManager () const ;
			LogManager* getLogManager () const ;
			MeshManager* getMeshManager () const ;
			NodeManager* getNodeManager () const ;
			ProgramManager* getProgramManager () const ;
			RasterStateManager* getRasterStateManager () const ;
			RenderContextManager* getRenderContextManager () const ;
			RenderQueueManager* getRenderQueueManager () const ;
			ResourceManager* getResourceManager () const ;
			SamplerManager* getSamplerManager () const ;
			ShaderManager* getShaderManager () const ;
			TextureManager* getTextureManager () const ;
			ViewportManager* getViewportManager () const ;
			bool getIsInitialized () const ;
			bool getHasRunToContinue () const ;
			bool getIsShuttingDown () const ;

			// Setters
			void setHasRunToContinue (bool value) ;

			// Lifetime
			bool initialize (const Configuration& config = Configuration()) ;
			void run (RenderContext* context, std::function<void ()> loopCallback = [] () {}) ;
			void shutdown () ;

			// Step by step
			bool frame (RenderContext* context) ;
			void tickForNewFrame (RenderContext* context) ;

		private :

			// Functions
			// Constructor
			System (bool isSingleton) noexcept ;
			System (const System&) = delete ;
			System (System&&) = delete ;

			// Operators
			System& operator= (const System&) = delete ;
			System& operator= (System&&) = delete ;

		private :
		
			// Attributes
			// Ui system used
			nkMemory::UniquePtr<nkWinUi::System> _uiSystem ;
			// Render system used
			nkMemory::UniquePtr<Renderer> _renderer ;

			// Loader
			nkMemory::UniquePtr<ContentLoader> _contentLoader ;

			// Trackers
			nkMemory::UniquePtr<MeshDataLinkTracker> _meshDataLinkTracker ;

			// Managers
			AsyncWorker* _asyncWorker ;
			BlendStateManager* _blendStateManager ;
			BufferManager* _bufferManager ;
			CameraManager* _cameraManager ;
			CompositorManager* _compositorManager ;
			DepthStencilStateManager* _depthStencilStateManager ;
			LogManager* _logManager ;
			MeshManager* _meshManager ;
			NodeManager* _nodeManager ;
			ProgramManager* _programManager ;
			RasterStateManager* _rasterStateManager ;
			RenderContextManager* _renderContextManager ;
			RenderQueueManager* _renderQueueManager ;
			ResourceManager* _resourceManager ;
			SamplerManager* _samplerManager ;
			ShaderManager* _shaderManager ;
			TextureManager* _textureManager ;
			ViewportManager* _viewportManager ;

			// Witnesses
			bool _initialized ;
			bool _hasRunToContinue ;
			bool _isShuttingDown ;

		private :

			friend class nkCommon::MaybeSingletonClass<System> ;
	} ;
}